/* 
  在字符串中获取数字(getNumberOfString)
  数组去重(uniq)
  对象数组去重，id重复的多个项，某个属性(prop)的值相加(uniqBy)
  数组排序，传入sort则从大到小排序，传入reverse则从小到大排序(arraySort)
  对象数组排序，传入sort则从大到小排序，传入reverse则从小到大排序(objArraySort)
  1维的对象数组，根据每个对象的parentId属性生成树形结构的baseNode对象(getTreeByParentId)
  获取URL中，?后面参数的key值与value值(getUrlParams)
  对象类型判断(typeJudgment)
  初始化对象的方法(clearObj)
  通过JS实现自适应布局(adaptiveLayout)
  防抖(debounce)
  节流(thorttle)
  函数加载JS文件(loadScript)
*/


// 在字符串中获取数字(getNumberOfString)
export function getNumberOfString(str) {
  return str.match(/\d+(.\d+)?/g);
}
//getNumberOfString("大米:2.57斤/元,白菜:3.65元/斤")

// 数组去重(uniq)
export function uniq(arr) {
  var newArr = [];
  arr.forEach(function(item) {
    if (newArr.indexOf(item) === -1) {
      newArr.push(item);
    }
  })
  return newArr;
}


// 对象数组去重，id重复的多个项，某个属性(prop)的值相加(uniq)    prop可传可不传
/**
 * @arr  对象数组
 * @id  去重所必要的唯一标识
 * @prop  哪个属性需要累加，可不填
*/
export function uniqBy(arr, id, prop) {
  arr = JSON.parse(JSON.stringify(arr))
  var filterItemArr = [], filterItemIdArr = []
  arr.forEach(item => {
    var index = filterItemIdArr.indexOf(item[id])
    if (index === -1) {
      filterItemArr.push(item)
      filterItemIdArr.push(item[id])
      return
    }
    if (!prop) return
    filterItemArr[index][prop] += item[prop]
  })
  return filterItemArr
}
/* var arr = [
  { "id": 4, "commodityId": "11", "commodityCode": "11", "commodityName": "巴氏染色液", "batchNumber": 21, "skuId": 10, "commodityState": "可销", "allocableInventory": 10, "orderQuantity": 5, "commoditySpecifications": "22", "validity": "2022-02-09", "qualityState": "合格" },
  { "id": 3, "commodityId": "11", "commodityCode": "11", "commodityName": "巴氏染色液", "batchNumber": 21, "skuId": 10, "commodityState": "可销", "allocableInventory": 240, "orderQuantity": 5, "commoditySpecifications": "22", "validity": "2022-02-09", "qualityState": "合格" },
  { "id": 1, "commodityId": "11", "commodityCode": "11", "commodityName": "巴氏染色液", "batchNumber": 21, "skuId": 10, "commodityState": "可销", "allocableInventory": 192, "orderQuantity": 5, "commoditySpecifications": "22", "validity": "2022-02-09", "qualityState": "合格" },
  { "id": 3, "commodityId": "11", "commodityCode": "11", "commodityName": "巴氏染色液", "batchNumber": 21, "skuId": 10, "commodityState": "可销", "allocableInventory": 235, "orderQuantity": 35, "commoditySpecifications": "22", "validity": "2022-02-09", "qualityState": "合格" },
  { "id": 4, "commodityId": "11", "commodityCode": "11", "commodityName": "巴氏染色液", "batchNumber": 21, "skuId": 10, "commodityState": "可销", "allocableInventory": 5, "orderQuantity": 5, "commoditySpecifications": "22", "validity": "2022-02-09", "qualityState": "合格" }
]
console.log(uniqBy(arr, "id", "orderQuantity")) */


// 数组排序，传入sort则从大到小排序，传入reverse则从小到大排序(arraySort)
export function arraySort(arr, sort) {
  var newArr = arr.sort(function(a, b) {
    if (a > b) { return 1 }
    if (a < b) { return -1 }
    if (a === b) { return 0 }
  });
  if (sort === "reverse") {
    return newArr.reverse();
  }
  return newArr;
}


// 对象数组排序，根据某个属性排序。传入sort则从大到小排序，传入reverse则从小到大排序(objArraySort)
export function objArraySort(arr, prop, sort) {
  var newArr = arr.sort(function(a, b) {
    if (a[prop] > b[prop]) { return 1; }
    if (a[prop] < b[prop]) { return -1; }
    if (a[prop] === b[prop]) { return 0; }
  })
  if (sort === "reverse") {
    return newArr.reverse();
  }
  return newArr;
}


// 1维的对象数组，根据每个对象的parentId属性生成树形结构的baseNode对象(getTreeByParentId)
export function getTreeByParentId(arr, nodeId, parentId) {
  // 拷贝一份新的数组，防止污染原数组
  arr = JSON.parse(JSON.stringify(arr))
  // 获取树状结构的根节点
  var baseNode = {}
  for (var i = 0, len = arr.length; i < len; i++) {
    if(typeof arr[i][parentId] !== "number" && (typeof arr[i][parentId] !== "string" || arr[i][parentId] === "")) {
      baseNode = arr.splice(i, 1)[0]
      break;
    }
  }
  function getTree(currentNode, arr) {
    // 获取当前元素的各个子元素
    currentNode.children = []
    for (var i = 0; i < arr.length; i++) {
      if (arr[i][parentId] === currentNode[nodeId]) {
        currentNode.children.push(arr[i])
        // 在arr[i]元素push到children属性里面之后，arr[i]就可以在arr中删掉了
        arr.splice(i, 1)
        i--;
      }
    }
    // 判断当前元素的children属性是否为空，不为空则递归
    if (currentNode.children.length !== 0 ) {
      currentNode.children.forEach(function(item) {
        getTree(item, arr)
      })
    }
  }
  getTree(baseNode, arr)
  return baseNode;
}
// 提供一个测试数据
/* [
  { id: '1', name: '2', parentId: null, rank: 1 },
  { id: '2', name: '2-1', parentId: '1', rank: 1 },
  { id: '3', name: '2-2', parentId: '1', rank: 1 },
  { id: '4', name: '2-3', parentId: '1', rank: 1 },
  { id: '5', name: '2-1-1', parentId: '2', rank: 1},
  { id: '6', name: '2-2-1', parentId: '3', rank: 1},
  { id: '7', name: '2-3-1', parentId: '4', rank: 1},
  { id: '8', name: '2-1-1-1', parentId: '5', rank: 1},
  { id: '9', name: '2-1-1-2', parentId: '5', rank: 1},
  { id: '10', name: '2-1-1-3', parentId: '5', rank: 1},
] */


// 获取URL中，?后面参数的key值与value值(getUrlParams)
export function getUrlParams(url) {
  var str = url || window.location.href;
  var obj = {};
  var num = str.indexOf("?") + 1;
  var url = str.slice(num);
  var urlParamsArr = url.split("&");
  urlParamsArr.forEach(function(item, index) {
      var paramsArr = item.split("=")
      obj[paramsArr[0]] = paramsArr[1]
  })
  return obj;
}


// 对象类型判断(typeJudgment)
export const typeJudgment = (function() {
  const type = ['Number', 'String', 'Boolean', 'Object', 'Function', 'Array', 'Date', 'RegExp', 'Error', 'Map', 'Set', 'Promise']
  return type.reduce((accu, item) => {
    accu[`is${item}`] = (target) => Object.prototype.toString.call(target) === `[object ${item}]`
    return accu
  }, {})
})()


// 初始化对象的方法  clearObj(obj, ['id'], { number: 0, string: 'all' });  1参：obj。  2参：1级属性中，不打算初始化的属性。  3参：属性中boolean/string/number 初始化成我们指定的值。
// （数组初始化为[]，只支持包含string、number、boolean、obj、array的对象）
export function clearObj(obj, excludeArr = [], formatProperties = { string: '', number: '', boolean: '' }) {
  const newObj = {}
  for (let key in obj) {
    if (excludeArr.includes(key)) { newObj[key] = JSON.parse(JSON.stringify(obj[key])); continue }
    switch (Object.prototype.toString.call(obj[key])) {
      case '[object Object]':
        newObj[key] = clearObj(JSON.parse(JSON.stringify(obj[key])), excludeArr, formatProperties)
        break;
      case '[object Array]':
        newObj[key] = []
        break;
      case '[object Number]':
        newObj[key] = formatProperties.hasOwnProperty('number') ? formatProperties.number : ''
        break;
      case '[object Boolean]':
        newObj[key] = formatProperties.hasOwnProperty('boolean') ? formatProperties.boolean : ''
        break;
      default:
        newObj[key] = formatProperties.hasOwnProperty('string') ? formatProperties.string : ''
        break;
    }
  }
  return newObj
}
/**
  const obj = { id: 1, money: 10, objType: ['前端', '后端'], form: { name: '小王', age: 18, job: ['打机', '泡妞'], info: { height: '180cm' } }, hasWife: false }
  const initObj = clearObj(obj, ['id'], { number: 0, string: 'all' })
  console.log(initObj)
*/


// 通过JS实现自适应布局(adaptiveLayout)
// 在一些老项目中，没有npm，只能通过js来实现页面自适应时就调用此方法。
export function adaptiveLayout() {
  const baseWidth = 1920;
  const baseHeight = 1080;
  let timer = null;
  let calcScale = function () {
    let windowInnerWidth = window.innerWidth;
    let windowInnerHeight = window.innerHeight;
    // let ratioW = baseWidth / windowInnerWidth;
    let ratioW = windowInnerWidth / baseWidth;
    // let ratioH = baseHeight / windowInnerHeight;
    let ratioH = windowInnerHeight / baseHeight;
    console.log(windowInnerWidth, windowInnerHeight)
    document.body.style.width = baseWidth + 'px';
    document.body.style.height = baseHeight + 'px';
    document.body.style.transformOrigin = 'left top';
    document.body.style.transform = `scale(${ratioW})`;
  }
  calcScale();
  window.onresize = function () {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(calcScale, 300)
  }
}


// 防抖(debounce)
/** 
 * @fn  绑定在对象事件上的函数
 * @wait  定时器在几秒后运行fn函数
*/
// 此方法要在mounted或全局里，绑定给元素的某些事件上，防止timer被重复声明覆盖。
export function debounce(fn, wait) {
  var timer = null
  return function() {
    var _this = this
    var args = arguments
    if (timer) { clearTimeout(timer) }
    timer = setTimeout(function() {
      fn.apply(_this, args)
      timer = null
    }, wait)
  }
}
/* var name = "张三"
// debounce函数内能访问到name，是因为name声明的作用域，与window.onresize声明的作用域相同
window.onresize = debounce(function(event) { console.log("触发事件", name) }, 500) */

// 这个是不用绑定在元素上，可以直接调用的通用防抖事件。适用在vue中onClick绑定事件onClickHandle方法中调用
/* function debounce(fn, wait) {
  var args = arguments, that = this
  if (window.submitTimer) { clearTimeout(window.submitTimer) }
  window.submitTimer = setTimeout(function() {
    fn.apply(that, args)
    window.submitTimer = null
  }, wait)
  window.addEventListener("beforeunload", function(event) {
    clearTimeout(window.submitTimer)
  });
} */
/* this.age = 18
var people = "Lewin"
this.$common.debounce(() => { console.log("我来打印信息", people, this.age) }, 600) */


// 节流(thorttle)
export function thorttle(fn, wait) {
  var timer = null
  return function() {
    var _this = this
    var args = arguments
    if (timer) return
    timer = setTimeout(function() {
      fn.apply(_this, args)
      timer = null
    }, wait)
  }
}
/* var name = "张三"
window.onresize = thorttle(function(event) { console.log("触发事件", name) }, 500) */


// 函数加载JS文件(loadScript)
export function loadScript(src, callback) {
  var script = document.createElement('script'),
   head = document.getElementsByTagName('head')[0];
  script.type = 'text/javascript';
  script.charset = 'UTF-8';
  script.src = src;
  if (script.addEventListener) {
   script.addEventListener('load', function () {
    callback();
   }, false);
  } else if (script.attachEvent) {
    script.attachEvent('onreadystatechange', function () {
    var target = window.event.srcElement;
    if (target.readyState == 'loaded') {
      callback();
    }
   });
  }
  head.appendChild(script);
}
// 调用
/* loadScript('http://cdn.staticfile.org/jquery/1.6.2/jquery.min.js',function(){
 console.log('onload');
}); */
